home *** CD-ROM | disk | FTP | other *** search
- /**
- * Scout - The Amiga System Monitor
- *
- *------------------------------------------------------------------
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * You must not use this source code to gain profit of any kind!
- *
- *------------------------------------------------------------------
- *
- * @author Andreas Gelhausen
- * @author Richard Körber <rkoerber@gmx.de>
- */
-
- #include "system_headers.h"
-
- struct TasksCallbackUserData {
- APTR ud_List;
- ULONG ud_Count;
- };
-
- struct CPUCheckChangeMessage {
- ULONG methodID;
- ULONG value;
- };
-
- BOOL timer_ticking = FALSE;
-
- struct ScoutPatchSemaphore {
- struct SignalSemaphore sps_Semaphore;
- ULONG sps_SemaphoreSize;
- UWORD sps_Version;
- UWORD sps_Revision;
- UBYTE sps_SemaphoreName[32];
- ULONG sps_CodeSize;
- ULONG sps_Reserved[5];
- UBYTE sps_Code[1];
- };
-
- struct ScoutPatchSemaphore *patchsem = NULL;
-
- VOID __asm (*cleartaskdata) (VOID) = NULL;
- LONG __asm (*gettaskdata) (register __d0 struct Task *) = NULL;
- struct Task * __asm (*getaddedtask) (VOID) = NULL;
- char *switchstate = NULL;
-
- LONG totalmicros,cpuseconds = 1,cpumicros = 0;
-
- #define SCOUT_SEMA_NAME "« Scout's CPU patch »"
- #define CHEATTASK_STACKSIZE 1024
- #define CHEATTASK_NAME "« Scout's cheat task »"
- struct Task *cheattask = NULL;
-
- static __asm __saveds LONG taskslist_con2func(register __a2 Object *obj, register __a1 struct NList_ConstructMessage *msg, register __a0 struct Hook *hook)
- {
- return AllocListEntry(msg->pool, msg->entry, sizeof(struct TaskEntry));
- }
-
- MakeHook(taskslist_con2hook, taskslist_con2func);
-
- static __asm __saveds LONG taskslist_des2func(register __a2 Object *obj, register __a1 struct NList_DestructMessage *msg, register __a0 struct Hook *hook)
- {
- FreeListEntry(msg->pool, &msg->entry);
-
- return 0;
- }
-
- MakeHook(taskslist_des2hook, taskslist_des2func);
-
- static __asm __saveds LONG taskslist_dsp2func(register __a2 Object *obj, register __a1 struct NList_DisplayMessage *msg, register __a0 struct Hook *hook)
- {
- struct TaskEntry *te = (struct TaskEntry *)msg->entry;
-
- if (te) {
- msg->strings[0] = te->te_Address;
- msg->strings[1] = te->te_Name;
- msg->strings[2] = te->te_CPU;
- msg->strings[3] = te->te_Type;
- msg->strings[4] = te->te_Pri;
- msg->strings[5] = te->te_Num;
- msg->strings[6] = te->te_State;
- msg->strings[7] = te->te_SigWait;
- msg->strings[8] = te->te_FreeStack;
- } else {
- msg->strings[0] = "Address";
- msg->strings[1] = "ln_Name";
- msg->strings[2] = "CPU %";
- msg->strings[3] = "ln_Type";
- msg->strings[4] = "ln_Pri";
- msg->strings[5] = "NUM";
- msg->strings[6] = "State";
- msg->strings[7] = "SigWait";
- msg->strings[8] = "Free Stack";
- msg->preparses[0] = MUIX_B;
- msg->preparses[1] = MUIX_B;
- msg->preparses[2] = MUIX_B;
- msg->preparses[3] = MUIX_B;
- msg->preparses[4] = MUIX_B;
- msg->preparses[5] = MUIX_B;
- msg->preparses[6] = MUIX_B;
- msg->preparses[7] = MUIX_B;
- msg->preparses[8] = MUIX_B;
- }
-
- return 0;
- }
-
- MakeHook(taskslist_dsp2hook, taskslist_dsp2func);
-
- static LONG taskslist_cmp2colfunc( struct TaskEntry *te1,
- struct TaskEntry *te2,
- ULONG column )
- {
- LONG pri1, pri2;
-
- switch (column) {
- case 0: return stricmp(te1->te_Address, te2->te_Address);
- case 1: return stricmp(te1->te_Name, te2->te_Name);
- case 2: return stricmp(te1->te_CPU, te2->te_CPU);
- case 3: return stricmp(te1->te_Type, te2->te_Type);
- case 4: IsDec(te1->te_Pri, &pri1); IsDec(te2->te_Pri, &pri2); return pri2 - pri1;
- case 5: return stricmp(te1->te_Num, te2->te_Num);
- case 6: return stricmp(te1->te_State, te2->te_State);
- case 7: return stricmp(te1->te_SigWait, te2->te_SigWait);
- case 8: return stricmp(te1->te_FreeStack, te2->te_FreeStack);
- }
- }
-
- static __asm __saveds LONG taskslist_cmp2func(register __a2 Object *obj, register __a1 struct NList_CompareMessage *msg, register __a0 struct Hook *hook)
- {
- LONG cmp;
- struct TaskEntry *te1, *te2;
- ULONG col1, col2;
-
- te1 = (struct TaskEntry *)msg->entry1;
- te2 = (struct TaskEntry *)msg->entry2;
-
- col1 = msg->sort_type & MUIV_NList_TitleMark_ColMask;
- col2 = msg->sort_type2 & MUIV_NList_TitleMark2_ColMask;
-
- if (msg->sort_type == MUIV_NList_SortType_None) return 0;
-
- if (msg->sort_type & MUIV_NList_TitleMark_TypeMask) {
- cmp = taskslist_cmp2colfunc(te2, te1, col1);
- } else {
- cmp = taskslist_cmp2colfunc(te1, te2, col1);
- }
-
- if (cmp != 0 || col1 == col2) return cmp;
-
- if (msg->sort_type2 & MUIV_NList_TitleMark2_TypeMask) {
- cmp = taskslist_cmp2colfunc(te2, te1, col2);
- } else {
- cmp = taskslist_cmp2colfunc(te1, te2, col2);
- }
-
- return cmp;
- }
-
- MakeHook(taskslist_cmp2hook, taskslist_cmp2func);
-
- static __asm __saveds void cpuinterval_callfunc( register __a0 struct Hook *hook,
- register __a2 Object *obj,
- register __a1 UBYTE **contents )
- {
- struct TasksWinData *twd = INST_DATA(OCLASS(obj), obj);
- ULONG i;
- LONG micros = 0;
- UBYTE text[8];
-
- stccpy(text, *contents, sizeof(text));
-
- i = 0;
- while (text[i] != '\0' && text[i] != '.') i++;
-
- if (text[i] == '.') {
- ULONG t, j;
-
- t = 1;
- text[i] = '\0';
- while (isdigit(text[++i])) {
- if (j = (ULONG)(text[i] - '0')) {
- t *= 10;
- micros += (1000000 / t) * j;
- }
- }
- }
-
- cpumicros = micros;
- cpuseconds = atol((char *)&text);
- strcpy(updatetimetext, *contents);
-
- if (twd->twd_TimerHandlerAdded) {
- DoMethod(twd->twd_Application, MUIM_Application_RemInputHandler, &twd->twd_TimerHandler);
- twd->twd_TimerHandler.ihn_Millis = (cpuseconds * 1000) + (cpumicros / 1000);
- DoMethod(twd->twd_Application, MUIM_Application_AddInputHandler, &twd->twd_TimerHandler);
- }
- }
-
- MakeHook(cpuinterval_callhook, cpuinterval_callfunc);
-
- static __asm __saveds ULONG realstring_editfunc( register __a0 struct Hook *hook, register __a2 struct SGWork *sgw, register __a1 ULONG *msg )
- {
- ULONG return_code;
- ULONG i = 0, punkte = 0, notzeros = 0;
-
- return_code = ~0L;
-
- if (*msg == SGH_KEY) {
- if (sgw->EditOp == EO_REPLACECHAR || sgw->EditOp == EO_INSERTCHAR) {
- while (sgw->WorkBuffer[i]) {
- if (sgw->WorkBuffer[i++] == '.') punkte++;
- }
- if (punkte > 1 || (!isdigit(sgw->Code) && sgw->Code != '.')) {
- sgw->Actions |= SGA_BEEP;
- sgw->Actions &= ~SGA_USE;
- }
- } else if (sgw->EditOp == EO_ENTER) {
- while (sgw->WorkBuffer[i]) {
- if (sgw->WorkBuffer[i] >= '1' && sgw->WorkBuffer[i] <= '9') notzeros++;
- i++;
- }
- if (notzeros > 0) {
- sgw->Actions |= SGA_BEEP;
- sgw->Actions &= ~SGA_END;
- }
- }
- } else {
- return_code = 0;
- }
-
- return return_code;
- }
-
- MakeHook(realstring_edithook, realstring_editfunc);
-
- static void cheattask_func( void )
- {
- while (TRUE) {}
- }
-
- static struct Task *AddCheatTask( void )
- {
- struct Task *result;
-
- if (result = tbAllocVecPooled(globalPool, CHEATTASK_STACKSIZE + sizeof(struct Task))) {
- result->tc_SPLower = (void *)(sizeof(struct Task) + (ULONG)result);
- result->tc_SPUpper = (void *)(CHEATTASK_STACKSIZE + sizeof(struct Task) + (ULONG)result);
- result->tc_SPReg = result->tc_SPUpper;
-
- result->tc_Node.ln_Name = CHEATTASK_NAME;
- result->tc_Node.ln_Pri = -128;
- result->tc_Node.ln_Type = NT_TASK;
-
- AddTask(result, (APTR)&cheattask_func, NULL);
- }
-
- return result;
- }
-
- static void RemoveCheatTask( void )
- {
- if (cheattask) {
- RemTask(cheattask);
- tbFreeVecPooled(globalPool, cheattask);
- cheattask = NULL;
- }
- }
-
- struct Task *TaskExists( struct Task *tasktofind )
- {
- struct Task *task, *result = NULL;
-
- if (tasktofind == myprocess) return myprocess;
-
- Forbid();
-
- ITERATE_LIST(&SysBase->TaskReady, struct Task *, task) {
- if (task == tasktofind) {
- result = task;
- break;
- }
- }
-
- if (result == NULL) {
- ITERATE_LIST(&SysBase->TaskWait, struct Task *, task) {
- if (task == tasktofind) {
- result = task;
- break;
- }
- }
- }
-
- Permit();
-
- return result;
- }
-
- UBYTE *GetTaskState( UBYTE state,
- ULONG waitmask )
- {
- switch (state) {
- case TS_FROZEN: return txtTaskStateFrozen;
- case TS_ADDED: return txtTaskStateAdded;
- case TS_RUN: return txtTaskStateRunning;
- case TS_READY: return txtTaskStateReady;
- case TS_WAIT:
- switch (waitmask) {
- case SIGF_ABORT: return txtTaskStateWaitAbort;
- case SIGF_CHILD: return txtTaskStateWaitChild;
- case SIGF_SINGLE: return txtTaskStateWaitSemaphore;
- case SIGF_INTUITION: return txtTaskStateWaitIntuition;
- case SIGF_NET: return txtTaskStateWaitNet;
- case SIGF_DOS: return txtTaskStateWaitDOS;
- case SIGBREAKF_CTRL_C: return txtTaskStateWaitBreakC;
- case SIGBREAKF_CTRL_D: return txtTaskStateWaitBreakD;
- case SIGBREAKF_CTRL_E: return txtTaskStateWaitBreakE;
- case SIGBREAKF_CTRL_F: return txtTaskStateWaitBreakF;
- case 0x00000000: return txtTaskStateSuspended;
- default: return txtTaskStateWaiting;
- }
- case TS_EXCEPT: return txtTaskStateExcept;
- case TS_REMOVED: return txtTaskStateRemoved;
- case TS_INVALID: return txtTaskStateInvalid;
- default: return txtTaskStateUnknown;
- }
- }
-
- UBYTE *GetNodeType( UBYTE type )
- {
- switch (type) {
- case NT_TASK: return txtNodeTypeTask;
- case NT_INTERRUPT: return txtNodeTypeInterrupt;
- case NT_DEVICE: return txtNodeTypeDevice;
- case NT_MSGPORT: return txtNodeTypeMsgPort;
- case NT_MESSAGE: return txtNodeTypeMessage;
- case NT_FREEMSG: return txtNodeTypeFreeMsg;
- case NT_REPLYMSG: return txtNodeTypeReplyMsg;
- case NT_RESOURCE: return txtNodeTypeResource;
- case NT_LIBRARY: return txtNodeTypeLibrary;
- case NT_MEMORY: return txtNodeTypeMemory;
- case NT_SOFTINT: return txtNodeTypeSoftInt;
- case NT_FONT: return txtNodeTypeFont;
- case NT_PROCESS: return txtNodeTypeProcess;
- case NT_SEMAPHORE: return txtNodeTypeSemaphore;
- case NT_SIGNALSEM: return txtNodeTypeSignalSem;
- case NT_BOOTNODE: return txtNodeTypeBootNode;
- case NT_KICKMEM: return txtNodeTypeKickMem;
- case NT_GRAPHICS: return txtNodeTypeGraphics;
- case NT_DEATHMESSAGE: return txtNodeTypeDeathMessage;
- case NT_USER: return txtNodeTypeUser;
- case NT_EXTENDED: return txtNodeTypeExtended;
- case NT_UNKNOWN: return txtNodeTypeUnknown;
- default: return txtNodeTypeInvalid;
- };
- }
-
- UBYTE *GetTaskName( struct Task *task,
- UBYTE *buffer,
- ULONG maxlen )
- {
- buffer[0] = 0x00;
-
- if (task) {
- struct Process *pr = (struct Process *)task;
-
- if (task->tc_Node.ln_Type == NT_PROCESS && pr->pr_CLI != (BPTR)NULL) {
- struct CommandLineInterface *cli= (struct CommandLineInterface *)BADDR(pr->pr_CLI);
-
- if (cli->cli_Module != (BPTR)NULL && cli->cli_CommandName != (BPTR)NULL) {
- b2cstrn(cli->cli_CommandName, buffer, maxlen);
- }
- }
-
- if ((task->tc_Node.ln_Type == NT_PROCESS || task->tc_Node.ln_Type == NT_TASK) && task->tc_Node.ln_Succ != NULL) {
- ULONG l;
-
- if ((l = strlen(buffer)) > 0) {
- _snprintf(buffer + l, maxlen - l, " [%s]", nonetest(task->tc_Node.ln_Name));
- } else {
- stccpy(buffer, nonetest(task->tc_Node.ln_Name), maxlen);
- }
- } else {
- stccpy(buffer, txtNoTask, maxlen);
- }
- } else {
- stccpy(buffer, nonetest(NULL), maxlen);
- }
-
- return buffer;
- }
-
- static void GetCPUUsage( struct Task *task,
- struct TaskEntry *te )
- {
- if (totalmicros = *((ULONG *) ((ULONG)&TotalMicros1 + 4 - (ULONG)&MySwitch + CodeAddress))) {
- ULONG cpu, zehntel;
-
- cpu = (*gettaskdata)(task);
-
- zehntel = UDivMod32(totalmicros, 10000);
- if (zehntel == 0) zehntel = 1;
-
- zehntel = UDivMod32(cpu, zehntel);
- cpu = UDivMod32(zehntel, 100);
- zehntel -= UMult32(cpu, 100);
- if (cpu > 99) {
- cpu = 100;
- zehntel = 0;
- }
- _snprintf(te->te_CPU, sizeof(te->te_CPU), "%3ld.%02ld", cpu, zehntel);
- }
- }
-
- static void UpdateTaskEntry( struct Task *task,
- struct TaskEntry *te,
- BOOL cpuflag )
- {
- _snprintf(te->te_Pri, sizeof(te->te_Pri), "%4ld", task->tc_Node.ln_Pri);
- stccpy(te->te_State, GetTaskState((UBYTE)task->tc_State, task->tc_SigWait), sizeof(te->te_State));
- _snprintf(te->te_SigWait, sizeof(te->te_SigWait), "$%08lx", task->tc_SigWait);
-
- if ((ULONG)task->tc_SPUpper >= (ULONG)task->tc_SPReg &&
- (ULONG)task->tc_SPReg >= (ULONG)task->tc_SPLower) {
- LONG stackFree;
-
- stackFree = (ULONG)task->tc_SPReg - (ULONG)task->tc_SPLower;
- if (stackFree >= 512) {
- _snprintf(te->te_FreeStack, sizeof(te->te_FreeStack), "%8lD", stackFree);
- } else {
- _snprintf(te->te_FreeStack, sizeof(te->te_FreeStack), MUIX_PH "%8lD" MUIX_PT, stackFree);
- }
- } else {
- // Stackpointer is out of limits, this program is most probably an AmigaE program
- stccpy(te->te_FreeStack, MUIX_PH "---" MUIX_PT, sizeof(te->te_FreeStack));
- }
-
- stccpy(te->te_CPU, " 0.00", sizeof(te->te_CPU));
-
- if (cpuflag && patchsem != NULL) GetCPUUsage(task, te);
- }
-
- static void GetTaskEntry( struct Task *task,
- struct TaskEntry *te,
- BOOL cpuflag )
- {
- te->te_Addr = task;
-
- _snprintf(te->te_Address, sizeof(te->te_Address), "$%08lx", task);
- GetTaskName(task, te->te_Name, sizeof(te->te_Name));
- healstring(te->te_Name);
- stccpy(te->te_Type, GetNodeType(task->tc_Node.ln_Type), sizeof(te->te_Type));
-
- if (task->tc_Node.ln_Type == NT_TASK || ((struct Process *)task)->pr_TaskNum == 0) {
- stccpy(te->te_Num, "---", sizeof(te->te_Num));
- } else {
- _snprintf(te->te_Num, sizeof(te->te_Num), "%3ld", ((struct Process *)task)->pr_TaskNum);
- }
-
- UpdateTaskEntry(task, te, cpuflag);
- }
-
- static void ReceiveList( void (* callback)( struct TaskEntry *te, void *userData ),
- void *userData )
- {
- struct TaskEntry *te;
-
- if (te = tbAllocVecPooled(globalPool, sizeof(struct TaskEntry))) {
- if (SendDaemon("GetTaskList")) {
- while (ReceiveDecodedEntry((UBYTE *)te, sizeof(struct TaskEntry))) {
- callback(te, userData);
- }
- }
-
- tbFreeVecPooled(globalPool, te);
- }
- }
-
- static void IterateList( void (* callback)( struct TaskEntry *te, void *userData ),
- void *userData )
- {
- struct MinList tmplist;
- struct TaskEntry *te, *_te;
- struct Task *task;
-
- NewList((struct List *)&tmplist);
-
- Forbid();
-
- if (te = AllocVec(sizeof(struct TaskEntry), MEMF_PUBLIC)) {
- GetTaskEntry(SysBase->ThisTask, te, FALSE);
- AddTail((struct List *)&tmplist, (struct Node *)te);
- }
-
- ITERATE_LIST(&SysBase->TaskReady, struct Task *, task) {
- if (te = AllocVec(sizeof(struct TaskEntry), MEMF_PUBLIC)) {
- GetTaskEntry(task, te, FALSE);
- AddTail((struct List *)&tmplist, (struct Node *)te);
- }
- }
-
- ITERATE_LIST(&SysBase->TaskWait, struct Task *, task) {
- if (te = AllocVec(sizeof(struct TaskEntry), MEMF_PUBLIC)) {
- GetTaskEntry(task, te, FALSE);
- AddTail((struct List *)&tmplist, (struct Node *)te);
- }
- }
-
- Permit();
-
- ITERATE_CHANGING_LIST(&tmplist, struct TaskEntry *, te, _te) {
- callback(te, userData);
- FreeVec(te);
- }
- }
-
- static void UpdateCallback( struct TaskEntry *te,
- void *userData )
- {
- struct TasksCallbackUserData *ud = (struct TasksCallbackUserData *)userData;
-
- InsertSortedEntry(ud->ud_List, te);
- ud->ud_Count++;
- }
-
- static void PrintCallback( struct TaskEntry *te,
- void *userData )
- {
- PrintFOneLine((BPTR)userData, " %s %-7.7s %4s %3s %-7.7s %s %s\n", te->te_Address, te->te_Type, te->te_Pri, te->te_Num, te->te_State, te->te_SigWait, te->te_Name);
- }
-
- static void SendCallback( struct TaskEntry *te,
- void *userData )
- {
- SendEncodedEntry((UBYTE *)te, sizeof(struct TaskEntry));
- }
-
- static ULONG __saveds mNew( struct IClass *cl,
- Object *obj,
- struct opSet *msg )
- {
- static UBYTE *CYA_CpuUsageText[] = { NULL, NULL, NULL, NULL };
-
- APTR taskslist, taskstext, taskscount, freezeButton, activateButton, signalButton, breakButton, updateButton, printButton, removeButton, priorityButton, moreButton, exitButton;
- APTR cpucount, cpuCycle, taskstext2;
-
- CYA_CpuUsageText[0] = txtCPUOff;
- CYA_CpuUsageText[1] = txtCPUFull;
- CYA_CpuUsageText[2] = txtCPUPercent;
-
- if (obj = (Object *)DoSuperNew(cl, obj,
- MUIA_HelpNode, TasksText,
- MUIA_Window_ID, MakeID('T','A','S','K'),
- WindowContents, VGroup,
-
- Child, taskslist = MyNListviewObject(MakeID('T','A','L','V'), "BAR,BAR,BAR P=" MUIX_R ",BAR P=" MUIX_C ",BAR P=" MUIX_R ",BAR P=" MUIX_R ",BAR P=" MUIX_C ",BAR,BAR P=" MUIX_R, &taskslist_con2hook, &taskslist_des2hook, &taskslist_dsp2hook, &taskslist_cmp2hook, TRUE),
- Child, MyBelowListview(&taskstext, &taskscount),
-
- Child, MyVSpace(4),
-
- Child, HGroup, MUIA_Group_SameSize, TRUE,
- Child, printButton = MakeButton(txtPrint),
- Child, freezeButton = MakeButton(txtFreeze),
- Child, activateButton = MakeButton(txtActivate),
- Child, HGroup,
- Child, MyLabel2(" CPU:"),
- Child, cpucount = GaugeObject,
- MUIA_Frame, MUIV_Frame_Gauge,
- MUIA_Gauge_Horiz, TRUE,
- MUIA_Gauge_Max, 100,
- MUIA_Gauge_InfoText, MUIX_PT "-----",
- MUIA_Gauge_Current, 0,
- End,
- End,
- Child, cpuCycle = CycleObject,
- MUIA_CycleChain, TRUE,
- MUIA_Weight, 0,
- MUIA_Cycle_Entries, CYA_CpuUsageText,
- MUIA_Cycle_Active, (opts.CpuDisplay) ? *opts.CpuDisplay : 0,
- End,
- Child, HGroup,
- Child, MyLabel2(txtSeconds),
- Child, taskstext2 = StringObject,
- StringFrame,
- MUIA_CycleChain, TRUE,
- MUIA_String_BufferPos, 0,
- MUIA_String_MaxLen, 6,
- MUIA_String_EditHook, &realstring_edithook,
- MUIA_String_Contents, updatetimetext,
- MUIA_String_Format, MUIV_String_Format_Center,
- End,
- End,
- End,
- Child, HGroup, MUIA_Group_SameSize, TRUE,
- Child, updateButton = MakeButton(txtUpdate),
- Child, removeButton = MakeButton(txtRemove),
- Child, signalButton = MakeButton(txtSignal),
- Child, breakButton = MakeButton(txtBreak),
- Child, priorityButton = MakeButton(txtPriority),
- Child, moreButton = MakeButton(txtMore),
- Child, exitButton = MakeButton(txtExit),
- End,
- End,
- TAG_MORE, msg->ops_AttrList))
- {
- struct TasksWinData *twd = INST_DATA(cl, obj);
- APTR parent;
-
- twd->twd_TaskList = taskslist;
- twd->twd_TaskText = taskstext;
- twd->twd_TaskCount = taskscount;
- twd->twd_RemoveButton = removeButton;
- twd->twd_PriorityButton = priorityButton;
- twd->twd_MoreButton = moreButton;
- twd->twd_SignalButton = signalButton;
- twd->twd_BreakButton = breakButton;
- twd->twd_FreezeButton = freezeButton;
- twd->twd_ActivateButton = activateButton;
- twd->twd_CPUGauge = cpucount;
- twd->twd_CPUCycle = cpuCycle;
- twd->twd_CPUCheck = (opts.CpuDisplay) ? *opts.CpuDisplay : 0;
- twd->twd_RefreshString = taskstext;
- twd->twd_TimerHandler.ihn_Object = obj;
- twd->twd_TimerHandler.ihn_Flags = MUIIHNF_TIMER;
- twd->twd_TimerHandler.ihn_Millis = (cpuseconds * 1000) + (cpumicros / 1000);
- twd->twd_TimerHandler.ihn_Method = MUIM_TasksWin_CPUCheckQuick;
- twd->twd_TimerHandlerAdded = FALSE;
-
- parent = (APTR)GetTagData(MUIA_Window_ParentWindow, (ULONG)NULL, msg->ops_AttrList);
- get(parent, MUIA_ApplicationObject, &twd->twd_Application);
-
- set(obj, MUIA_Window_Title, MyGetWindowTitle("TASKS & PROCESSES", twd->twd_Title, sizeof(twd->twd_Title)));
- set(obj, MUIA_Window_ActiveObject, taskslist);
- set(removeButton, MUIA_Disabled, TRUE);
- set(priorityButton, MUIA_Disabled, TRUE);
- set(moreButton, MUIA_Disabled, TRUE);
- set(freezeButton, MUIA_Disabled, TRUE);
- set(activateButton, MUIA_Disabled, TRUE);
- set(signalButton, MUIA_Disabled, TRUE);
- set(breakButton, MUIA_Disabled, TRUE);
- if (clientstate) {
- set(cpuCycle, MUIA_Disabled, TRUE);
- set(taskstext2, MUIA_Disabled, TRUE);
- }
-
- DoMethod(parent, MUIM_Window_AddChildWindow, obj);
- DoMethod(obj, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, MUIV_Notify_Application, 5, MUIM_Application_PushMethod, parent, 2, MUIM_Window_RemChildWindow, obj);
- DoMethod(taskslist, MUIM_Notify, MUIA_NList_Active, MUIV_EveryTime, obj, 1, MUIM_TasksWin_ListChange);
- DoMethod(taskslist, MUIM_Notify, MUIA_NList_DoubleClick, MUIV_EveryTime, obj, 1, MUIM_TasksWin_More);
- DoMethod(updateButton, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, MUIM_TasksWin_Update);
- DoMethod(printButton, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, MUIM_TasksWin_Print);
- DoMethod(removeButton, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, MUIM_TasksWin_Remove);
- DoMethod(moreButton, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, MUIM_TasksWin_More);
- DoMethod(priorityButton, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, MUIM_TasksWin_Priority);
- DoMethod(freezeButton, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, MUIM_TasksWin_Freeze);
- DoMethod(activateButton, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, MUIM_TasksWin_Activate);
- DoMethod(signalButton, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, MUIM_TasksWin_Signal);
- DoMethod(breakButton, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, MUIM_TasksWin_Break);
- DoMethod(exitButton, MUIM_Notify, MUIA_Pressed, FALSE, obj, 3, MUIM_Set, MUIA_Window_CloseRequest, TRUE);
- DoMethod(cpuCycle, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, obj, 2, MUIM_TasksWin_CPUCheckChange, MUIV_TriggerValue);
- DoMethod(taskstext2, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, obj, 3, MUIM_CallHook, &cpuinterval_callhook, MUIV_TriggerValue);
- DoMethod(taskslist, MUIM_NList_Sort3, MUIV_NList_Sort3_SortType_1, MUIV_NList_SortTypeAdd_None, MUIV_NList_Sort3_SortType_Both);
- // DoMethod(taskslist, MUIM_NList_Sort3, spalte, MUIV_NList_SortTypeAdd_None, MUIV_NList_Sort3_SortType_Both);
- }
-
- return (ULONG)obj;
- }
-
- static ULONG __saveds mDispose( struct IClass *cl,
- Object *obj,
- struct opSet *msg )
- {
- struct TasksWinData *twd = INST_DATA(cl, obj);
-
- if (twd->twd_TimerHandlerAdded) {
- DoMethod(twd->twd_Application, MUIM_Application_RemInputHandler, &twd->twd_TimerHandler);
- twd->twd_TimerHandlerAdded = FALSE;
- }
-
- set(obj, MUIA_Window_Open, FALSE);
- DoMethod(twd->twd_TaskList, MUIM_NList_Clear);
-
- RemoveCheatTask();
-
- return (DoSuperMethodA(cl, obj, msg));
- }
-
- static ULONG __saveds mUpdate( struct IClass *cl,
- Object *obj,
- Msg msg )
- {
- struct TasksWinData *twd = INST_DATA(cl, obj);
- struct TasksCallbackUserData ud;
-
- ApplicationSleep(TRUE);
- set(twd->twd_TaskList, MUIA_NList_Quiet, TRUE);
- DoMethod(twd->twd_TaskList, MUIM_NList_Clear);
-
- ud.ud_List = twd->twd_TaskList;
- ud.ud_Count = 0;
-
- if (clientstate) {
- ReceiveList(UpdateCallback, &ud);
- } else {
- IterateList(UpdateCallback, &ud);
- }
-
- SetCountText(twd->twd_TaskCount, ud.ud_Count);
- MySetContents(twd->twd_TaskText, "");
-
- set(twd->twd_TaskList, MUIA_NList_Quiet, FALSE);
- set(twd->twd_TaskList, MUIA_NList_Active, MUIV_NList_Active_Off);
- set(twd->twd_PriorityButton, MUIA_Disabled, TRUE);
- set(twd->twd_RemoveButton, MUIA_Disabled, TRUE);
- set(twd->twd_MoreButton, MUIA_Disabled, TRUE);
- set(twd->twd_FreezeButton, MUIA_Disabled, TRUE);
- set(twd->twd_ActivateButton, MUIA_Disabled, TRUE);
- set(twd->twd_SignalButton, MUIA_Disabled, TRUE);
- set(twd->twd_BreakButton, MUIA_Disabled, TRUE);
-
- DoMethod(obj, MUIM_TasksWin_CPUCheckChange, twd->twd_CPUCheck);
-
- ApplicationSleep(FALSE);
-
- return 0;
- }
-
- static ULONG __saveds mPrint( struct IClass *cl,
- Object *obj,
- Msg msg )
- {
- PrintTasks(NULL);
-
- return 0;
- }
-
- static ULONG __saveds mRemove( struct IClass *cl,
- Object *obj,
- Msg msg )
- {
- struct TasksWinData *twd = INST_DATA(cl, obj);
- struct TaskEntry *te;
-
- if (te = (struct TaskEntry *)GetActiveEntry(twd->twd_TaskList)) {
- if (MyRequest(msgYesNo, msgWantToRemoveTask, te->te_Type, te->te_Name)) {
- BOOL withPorts;
-
- withPorts = MyRequest(msgYesNo, msgWantToRemoveTaskWithStuff, te->te_Name);
-
- MyDoCommand("RemoveTask %s %s", te->te_Address, (withPorts) ? "WITHPORTS" : "");
- DoMethod(obj, MUIM_TasksWin_Update);
- }
- }
-
- return 0;
- }
-
- static ULONG __saveds mPriority( struct IClass *cl,
- Object *obj,
- Msg msg )
- {
- struct TasksWinData *twd = INST_DATA(cl, obj);
- struct TaskEntry *te;
-
- if (te = (struct TaskEntry *)GetActiveEntry(twd->twd_TaskList)) {
- LONG pri;
-
- pri = atol(te->te_Pri);
- if (GetPriority(te->te_Name, &pri)) {
- if (MyDoCommand("SetTaskPri %s %ld", te->te_Address, pri)) {
- _snprintf(te->te_Pri, sizeof(te->te_Pri), "%4ld", pri);
- RedrawActiveEntry(twd->twd_TaskList);
- }
- }
- }
-
- return 0;
- }
-
- static ULONG __saveds mMore( struct IClass *cl,
- Object *obj,
- Msg msg )
- {
- struct TasksWinData *twd = INST_DATA(cl, obj);
- struct TaskEntry *te;
-
- if (te = (struct TaskEntry *)GetActiveEntry(twd->twd_TaskList)) {
- struct Task *task;
- Forbid();
-
- if (task = MyFindTask(te->te_Address)) {
- APTR detailWin;
-
- if (detailWin = TasksDetailWindowObject,
- MUIA_Window_ParentWindow, obj,
- MUIA_Window_MaxChildWindowCount, (opts.SingleWindows) ? 1 : 0,
- End) {
- set(detailWin, MUIA_TasksDetailWin_Task, te);
- set(detailWin, MUIA_Window_Open, TRUE);
- }
-
- Permit();
- } else {
- Permit();
-
- MyRequest(msgErrorContinue, msgCantFindTask);
- DoMethod(obj, MUIM_TasksWin_Update);
- }
- }
-
- return 0;
- }
-
- static ULONG __saveds mListChange( struct IClass *cl,
- Object *obj,
- Msg msg )
- {
- struct TasksWinData *twd = INST_DATA(cl, obj);
- struct TaskEntry *te;
-
- if (te = (struct TaskEntry *)GetActiveEntry(twd->twd_TaskList)) {
- MySetContents(twd->twd_TaskText, "%s \"%s\"", te->te_Address, te->te_Name);
- set(twd->twd_PriorityButton, MUIA_Disabled, FALSE);
- set(twd->twd_RemoveButton, MUIA_Disabled, FALSE);
- if (!clientstate) {
- set(twd->twd_MoreButton, MUIA_Disabled, FALSE);
- set(twd->twd_CPUCycle, MUIA_Disabled, FALSE);
- }
- set(twd->twd_FreezeButton, MUIA_Disabled, FALSE);
- set(twd->twd_ActivateButton, MUIA_Disabled, FALSE);
- set(twd->twd_SignalButton, MUIA_Disabled, FALSE);
- set(twd->twd_BreakButton, MUIA_Disabled, FALSE);
- }
-
- return 0;
- }
-
- static ULONG __saveds mFreeze( struct IClass *cl,
- Object *obj,
- Msg msg )
- {
- struct TasksWinData *twd = INST_DATA(cl, obj);
- struct TaskEntry *te;
-
- if (te = (struct TaskEntry *)GetActiveEntry(twd->twd_TaskList)) {
- MyDoCommand("FreezeTask %s", te->te_Address);
- stccpy(te->te_State, GetTaskState(TS_FROZEN, 0), sizeof(te->te_State));
- RedrawActiveEntry(twd->twd_TaskList);
- }
-
- return 0;
- }
-
- static ULONG __saveds mActivate( struct IClass *cl,
- Object *obj,
- Msg msg )
- {
- struct TasksWinData *twd = INST_DATA(cl, obj);
- struct TaskEntry *te;
-
- if (te = (struct TaskEntry *)GetActiveEntry(twd->twd_TaskList)) {
- MyDoCommand("ActivateTask %s", te->te_Address);
- stccpy(te->te_State, GetTaskState(TS_WAIT, -1), sizeof(te->te_State));
- RedrawActiveEntry(twd->twd_TaskList);
- }
-
- return 0;
- }
-
- static ULONG __saveds mSignal( struct IClass *cl,
- Object *obj,
- Msg msg )
- {
- struct TasksWinData *twd = INST_DATA(cl, obj);
- struct TaskEntry *te;
-
- if (te = (struct TaskEntry *)GetActiveEntry(twd->twd_TaskList)) {
- ULONG sigs;
- APTR sigwin;
-
- IsUHex(te->te_SigWait, &sigs);
- if (sigwin = SignalWindowObject,
- MUIA_Window_ParentWindow, obj,
- End) {
- if (DoMethod(sigwin, MUIM_SignalWin_GetSignals, te->te_Name, &sigs)) {
- if (MyDoCommand("SignalTask %s $%08lx", te->te_Address, sigs)) {
- Delay(25);
- RedrawActiveEntry(twd->twd_TaskList);
- } else {
- DoMethod(obj, MUIM_TasksWin_Update);
- }
- }
- }
- }
-
- return 0;
- }
-
- static ULONG __saveds mBreak( struct IClass *cl,
- Object *obj,
- Msg msg )
- {
- struct TasksWinData *twd = INST_DATA(cl, obj);
- struct TaskEntry *te;
-
- if (te = (struct TaskEntry *)GetActiveEntry(twd->twd_TaskList)) {
- if (MyDoCommand("BreakTask %s", te->te_Address)) {
- Delay(25);
- RedrawActiveEntry(twd->twd_TaskList);
- } else {
- DoMethod(obj, MUIM_TasksWin_Update);
- }
- }
-
- return 0;
- }
-
- static ULONG __saveds mCPUCheckChange( struct IClass *cl,
- Object *obj,
- Msg msg )
- {
- struct TasksWinData *twd = INST_DATA(cl, obj);
- struct CPUCheckChangeMessage *cccm = (struct CPUCheckChangeMessage *)msg;
-
- twd->twd_CPUCheck = cccm->value;
-
- if (cccm->value != 0) {
- ULONG semasize, codesize;
-
- Forbid();
- patchsem = (struct ScoutPatchSemaphore *)FindSemaphore(SCOUT_SEMA_NAME);
- Permit();
-
- codesize = (ULONG)&CodeAddress - (ULONG)&MySwitch + 8;
- semasize = sizeof(struct ScoutPatchSemaphore) + codesize;
-
- if (patchsem != NULL &&
- patchsem->sps_SemaphoreSize == semasize &&
- patchsem->sps_CodeSize == codesize &&
- ((patchsem->sps_Version > version_ulong) || (patchsem->sps_Version == version_ulong && patchsem->sps_Revision >= revision_ulong))) {
- CodeAddress = &patchsem->sps_Code[0];
- } else {
- struct ScoutPatchSemaphore *sps;
-
- if (patchsem) {
- void (*switch_func)( void ) = (void (*)())OldSwitch;
-
- MyRequest(msgErrorContinue, msgFoundOldPatchSemaphore, patchsem->sps_Version, patchsem->sps_Revision, version_ulong, revision_ulong);
- Disable();
- *switchstate = 0;
- *((ULONG *)(-52 + (ULONG)SysBase)) = OldSwitch;
- *((ULONG *)(-280 + (ULONG)SysBase)) = OldAddTask;
- switch_func();
- sps = patchsem;
- patchsem = NULL;
- Enable();
- RemSemaphore(sps);
- FreeMem(sps, sps->sps_SemaphoreSize);
- }
-
- AsmTimerBase = TimerIORequest->tr_node.io_Device;
-
- if (sps = AllocMem(semasize, MEMF_ANY | MEMF_PUBLIC | MEMF_REVERSE)) {
- CodeAddress = &sps->sps_Code[0];
- OldSwitch = *((ULONG *)(-52 + (ULONG)SysBase));
- OldAddTask = *((ULONG *)(-280 + (ULONG)SysBase));
-
- // der Code darf erst nach dem Auslesen der Sprünge passieren, sonst werden für den Assembler-Teil falsche Adressen kopiert
- CopyMem(&MySwitch, sps->sps_Code, codesize);
-
- InitSemaphore(sps);
- sps->sps_Semaphore.ss_Link.ln_Name = &sps->sps_SemaphoreName[0];
- stccpy(sps->sps_SemaphoreName, SCOUT_SEMA_NAME, sizeof(sps->sps_SemaphoreName));
- sps->sps_SemaphoreSize = semasize;
- sps->sps_Version = version_ulong;
- sps->sps_Revision = revision_ulong;
- sps->sps_CodeSize = codesize;
- AddSemaphore(sps);
-
- SetPatches();
-
- patchsem = sps;
- } else {
- MyRequest(msgErrorContinue, msgCantInstallPatchSemaphore);
- }
- }
- }
-
- if (patchsem) {
- cleartaskdata = (void (* __asm)(void))((char *)&ClearTaskData - (char *)&MySwitch + CodeAddress);
- gettaskdata = (LONG (* __asm)(register __d0 struct Task *))((char *)&GetTaskData - (char *)&MySwitch + CodeAddress);
- getaddedtask = (struct Task * (* __asm)(void))((char *)&GetAddedTask - (char *)&MySwitch + CodeAddress);
- switchstate = (char *)&SwitchState - (char *)&MySwitch + CodeAddress;
-
- *switchstate = (char)cccm->value;
- // HandleTimerRequest(FALSE);
- (*cleartaskdata)();
-
- if (cccm->value == 2) {
- if (!cheattask) cheattask = AddCheatTask();
- } else {
- RemoveCheatTask();
- set(twd->twd_CPUGauge, MUIA_Gauge_Current, 0);
- set(twd->twd_CPUGauge, MUIA_Gauge_InfoText, MUIX_PT "-----");
- }
-
- // DoMethod(obj, MUIM_TasksWin_CPUCheck);
-
- if (cccm->value == 0) {
- if (twd->twd_TimerHandlerAdded) {
- DoMethod(twd->twd_Application, MUIM_Application_RemInputHandler, &twd->twd_TimerHandler);
- twd->twd_TimerHandlerAdded = FALSE;
- }
- } else {
- if (!twd->twd_TimerHandlerAdded) {
- DoMethod(twd->twd_Application, MUIM_Application_AddInputHandler, &twd->twd_TimerHandler);
- twd->twd_TimerHandlerAdded = TRUE;
- }
- }
-
- DoMethod(obj, MUIM_TasksWin_CPUCheck);
- }
-
- return 0;
- }
-
- static ULONG __saveds mCPUCheck( struct IClass *cl,
- Object *obj,
- Msg msg )
- {
- struct TasksWinData *twd = INST_DATA(cl, obj);
- struct TasksCallbackUserData ud;
- struct Task *task;
- BOOL changed;
- ULONG i, oldTaskCnt, sortCol;
-
- get(twd->twd_TaskList, MUIA_NList_Entries, &oldTaskCnt);
- get(twd->twd_TaskList, MUIA_NList_SortType, &sortCol);
- sortCol &= MUIV_NList_TitleMark_ColMask;
-
- ud.ud_List = twd->twd_TaskList;
- ud.ud_Count = oldTaskCnt;
-
- (*cleartaskdata)();
-
- while (task = (*getaddedtask)()) {
- if (TaskExists(task)) {
- GetTaskEntry(task, &twd->twd_NewEntry, (twd->twd_CPUCheck != 0));
- UpdateCallback(&twd->twd_NewEntry, &ud);
- }
- }
-
- changed = FALSE;
-
- for (i = 0; ; i++) {
- struct TaskEntry *old;
-
- DoMethod(twd->twd_TaskList, MUIM_NList_GetEntry, i, &old);
-
- if (old) {
- if (task = TaskExists(old->te_Addr)) {
- CopyMem(old, &twd->twd_CompareEntry, sizeof(struct TaskEntry));
- UpdateTaskEntry(task, old, twd->twd_CPUCheck);
- if (memcmp(old, &twd->twd_CompareEntry, sizeof(struct TaskEntry))) {
- if (sortCol != 2) DoMethod(twd->twd_TaskList, MUIM_NList_Redraw, i);
- changed = TRUE;
- }
- } else {
- DoMethod(twd->twd_TaskList, MUIM_NList_Remove, i);
- i--;
- ud.ud_Count--;
- }
- } else {
- break;
- }
- }
-
- if (ud.ud_Count != oldTaskCnt) SetCountText(twd->twd_TaskCount, ud.ud_Count);
- if (changed && sortCol == 2) DoMethod(twd->twd_TaskList, MUIM_List_Sort);
-
- if (twd->twd_CPUCheck == 2) {
- ULONG cheatcpu;
-
- cheatcpu = (*gettaskdata)(cheattask);
- if (totalmicros) {
- set(twd->twd_CPUGauge, MUIA_Gauge_InfoText, "%ld%%");
- set(twd->twd_CPUGauge, MUIA_Gauge_Current, UDivMod32(UMult32(totalmicros - cheatcpu, 100), totalmicros));
- }
- }
-
- return 0;
- }
-
- static ULONG __saveds mCPUCheckQuick( struct IClass *cl,
- Object *obj,
- Msg msg )
- {
- if (patchsem != NULL && *switchstate != 0) {
- DoMethod(obj, MUIM_TasksWin_CPUCheck);
- }
-
- return TRUE;
- }
-
- ULONG __asm __saveds TasksWinDispatcher( register __a0 struct IClass *cl,
- register __a2 Object *obj,
- register __a1 Msg msg )
- {
- switch (msg->MethodID) {
- case OM_NEW: return (mNew(cl, obj, (APTR)msg));
- case OM_DISPOSE: return (mDispose(cl, obj, (APTR)msg));
- case MUIM_TasksWin_Update: return (mUpdate(cl, obj, (APTR)msg));
- case MUIM_TasksWin_Print: return (mPrint(cl, obj, (APTR)msg));
- case MUIM_TasksWin_Remove: return (mRemove(cl, obj, (APTR)msg));
- case MUIM_TasksWin_Priority: return (mPriority(cl, obj, (APTR)msg));
- case MUIM_TasksWin_More: return (mMore(cl, obj, (APTR)msg));
- case MUIM_TasksWin_ListChange: return (mListChange(cl, obj, (APTR)msg));
- case MUIM_TasksWin_Freeze: return (mFreeze(cl, obj, (APTR)msg));
- case MUIM_TasksWin_Activate: return (mActivate(cl, obj, (APTR)msg));
- case MUIM_TasksWin_Signal: return (mSignal(cl, obj, (APTR)msg));
- case MUIM_TasksWin_Break: return (mBreak(cl, obj, (APTR)msg));
- case MUIM_TasksWin_CPUCheckChange: return (mCPUCheckChange(cl, obj, (APTR)msg));
- case MUIM_TasksWin_CPUCheck: return (mCPUCheck(cl, obj, (APTR)msg));
- case MUIM_TasksWin_CPUCheckQuick: return (mCPUCheckQuick(cl, obj, (APTR)msg));
- }
-
- return (DoSuperMethodA(cl, obj, msg));
- }
-
- void PrintTasks( char *filename )
- {
- BPTR handle;
-
- if (handle = HandlePrintStart(filename)) {
- PrintFOneLine(handle, "\n Address Type Pri NUM State SigWait Name\n\n");
- IterateList(PrintCallback, (void *)handle);
- }
-
- HandlePrintStop();
- }
-
- void SendTaskList( void )
- {
- IterateList(SendCallback, NULL);
- }
-
-